home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / modules / nessus-2.2.8.mo / usr / lib / nessus / plugins / qpkg.inc < prev    next >
Text File  |  2005-03-31  |  7KB  |  236 lines

  1. # -*- sh -*-
  2. # This script is copyright 2004 Michel Arboi <mikhail@nessus.org>
  3. # It is released under the GNU Public Licence (GPLv2)
  4. # $Revision: 1.11 $
  5.  
  6. global_var    qpkg_list;
  7.  
  8. # Retuns 1 if surely matches, -1 if surely does not match, NULL or 0 otherwise
  9. function qpkg_ver_cmp(ver, ref, op)
  10. {
  11.   local_var    inf, sup, eq;
  12.   local_var    r, v, i, n, nr, nv;
  13.  
  14.  
  15.   # Easy cases: identity
  16.   if (op == 'eq')
  17.    if (ver == ref) return 1; else return -1;
  18.   if (ver == ref)
  19.     if ('e' >< op) return 1; else return -1;
  20.  
  21.   if ('l' >< op) { inf = 1; sup = -1; } else { inf = -1; sup = 1; }
  22.   if ('e' >< op) { eq = 1; } else { eq = -1; }
  23.  
  24.   # -r0 treatement
  25.   v = eregmatch(string: ref, icase: 0, pattern: '^(.+)-r([0-9]+)+$');
  26.   if (isnull(v)) { ref_base = ref; ref_r = 0; }
  27.   else { ref_base = v[1]; ref_r = int(v[2]); }
  28.  
  29.   v = eregmatch(string: ver, icase: 0, pattern: '^(.+)-r([0-9]+)$');
  30.   if (isnull(v)) { ver_base = ver; ver_r = 0; }
  31.   else { ver_base = v[1]; ver_r = int(v[2]); }
  32.  
  33.   if (ver_base == ref_base)
  34.     if  (ver_r < ref_r) return inf;
  35.     else if (ver_r == ref_r) return eq;
  36.     else return sup;
  37.   # We have remove -r* at the end of the strings
  38.  
  39.   # alpha / beta
  40.   v = eregmatch(string: ver_base, icase: 0, pattern: '^(.+)_(alpha|beta)([0-9]+)$');
  41.   r = eregmatch(string: ref_base, icase: 0, pattern: '^(.+)_(alpha|beta)([0-9]+)$');
  42.   if (! isnull(v)) { ver_base = v[1]; vab = v[2]; vabN = int(v[3]); }
  43.   if (! isnull(r)) { ref_base = r[1]; rab = r[2]; rabN = int(r[3]); }
  44.   if (ver_base == ref_base)
  45.   {
  46.     # I supose that 1.30 is newer than 1.30_alpha3
  47.     if (! vab) vab = 'zzzz';
  48.     if (! rab) rab = 'zzzz';
  49.     if (vab < rab) return inf;
  50.     else if (vab > rab) return sup;
  51.     if (vabN < rabN) return inf;
  52.     else if (vabN > rabN) return sup;
  53.   }
  54.   # _alpha* has been removed
  55.  
  56.   # _pre*
  57.   # The result will probably be wrong if we compare 1.30_pre1 and 1.30_pre20020319
  58.   # but how are we supposed to solve such a case?
  59.   v = eregmatch(string: ver_base, icase: 0, pattern: '^(.+)_pre([0-9]+)$');
  60.   r = eregmatch(string: ref_base, icase: 0, pattern: '^(.+)_pre([0-9]+)$');
  61.   if (! isnull(v)) { ver_base = v[1]; vN = int(v[2]); }
  62.   if (! isnull(r)) { ref_base = r[1]; rN = int(r[2]); }
  63.   if (ver_base == ref_base)
  64.   {
  65.     # I supose that 1.30 is newer than 1.30_pre20020318
  66.     if (! vN && rN) return sup;
  67.     if (vN && ! rN) return inf;
  68.  
  69.     if (vN < rN) return inf;
  70.     else if (vN > rN) return sup;
  71.   }
  72.  
  73.   # _p*
  74.   v = eregmatch(string: ver_base, icase: 0, pattern: '^(.+)_p([0-9]+)$');
  75.   r = eregmatch(string: ref_base, icase: 0, pattern: '^(.+)_p([0-9]+)$');
  76.   if (! isnull(v)) { ver_base = v[1]; vN = int(v[2]); }
  77.   if (! isnull(r)) { ref_base = r[1]; rN = int(r[2]); }
  78.   if (ver_base == ref_base)
  79.   {
  80.     # 1.30_p2 is newer than 1.30
  81.     if (vN < rN) return inf;
  82.     else if (vN > rN) return sup;
  83.   }
  84.  
  85.   # _rc*
  86.   v = eregmatch(string: ver_base, icase: 0, pattern: '^(.+)_rc([0-9]+)$');
  87.   r = eregmatch(string: ref_base, icase: 0, pattern: '^(.+)_rc([0-9]+)$');
  88.   if (! isnull(v)) { ver_base = v[1]; vN = int(v[2]); }
  89.   if (! isnull(r)) { ref_base = r[1]; rN = int(r[2]); }
  90.   if (ver_base == ref_base)
  91.   {
  92.     # I supose that 1.30_rc3 is older than 1.30
  93.     if (! vN && rN) return inf;
  94.     if (vN && ! rN) return sup;
  95.  
  96.     if (vN < rN) return inf;
  97.     else if (vN > rN) return sup;
  98.   }
  99.  
  100.   # Date
  101.   if (op[0] != 'r') # special case for rge, rlt...
  102.   if (ref_base =~ "^[12][90][0-9]{2}\.?[0-9]{2}\.?[0-9]{2}$")
  103.     if (ver_base !~ "^[12][90][0-9]{2}\.?[0-9]{2}\.?[0-9]{2}$")
  104.     {
  105.       #display("qpkg_ver_cmp: do not know how to compare a date to something else\n");
  106.       return;
  107.     }
  108.     else
  109.     {
  110.       ref_base = int(ereg_replace(string: ref_base, pattern: ".", replace: ""));
  111.       ver_base = int(ereg_replace(string: ref_base, pattern: ".", replace: ""));
  112.       if (ver_base < ref_base) return inf;
  113.       else if (ver_base > ref_base) return sup;
  114.       else return eq;
  115.     }
  116.  
  117.   # Simple number
  118.   if (op[0] != 'r') # special case for rge, rlt...
  119.   if (ver_base =~ '^[0-9]+$' && ref_base =~ '^[0-9]+$')
  120.   {
  121.     v = int(ver_base); r = int(ref_base);
  122.     if (v < r) return inf;
  123.     else if (v > r) return sup;
  124.     else if (v == r) return eq;
  125.   }
  126.  
  127.   # Clasic version number
  128.   if (ver_base =~ "^[0-9.]+" && ref_base =~ "^[0-9.]+")
  129.   {
  130.     v = split(ver_base, sep: '.');
  131.     r = split(ref_base, sep: '.');
  132.     nv = max_index(v); nr = max_index(r);
  133.     if (nv < nr) n = nv; else n = nr;
  134.  
  135.     # special case for rge, rlt...
  136.     if (op[0] == 'r' && v[0] != r[0]) return -1;
  137.  
  138.     for (i = 0; i < n; i ++)
  139.      if (int(v[i]) < int(r[i])) return inf;
  140.      else if (int(v[i]) > int(r[i])) return sup;
  141.     # 1.6.3.1 > 1.6.3
  142.     if (nv < nr) return inf;
  143.     else if (nv > nr) return sup;
  144.     # if (v[i-1] == r[i-1]) return eq; - treated above
  145.     # 2.30 and 2.30b (should I process this like alpha/beta or -r* ?
  146.     v = eregmatch(string: ver_base, pattern: "^[0-9.]+([a-z]?)$");
  147.     r = eregmatch(string: ref_base, pattern: "^[0-9.]+([a-z]?)$");
  148.     if (! isnull(v) && ! isnull(r))
  149.       if (v[1] < r[1]) return inf;
  150.       else if (v[1] > r[1]) return sup;
  151.       else if (v[1] == r[1]) return eq;
  152.   }
  153.  
  154.   #display("qpkg_ver_cmp: do not known how to compare  ", ver, " ",op, " ", ref, "\n");
  155.   return;
  156. }
  157.  
  158. function qpkg_cmp(pkg, version, range)
  159. {
  160.   local_var    v, cmp, ver, from_qpkg, l, ret;
  161.  
  162.   if (isnull(range)) return;
  163. #display("version=", version, "\trange=", range, "\n");
  164.   v = split(range, sep: ' ');
  165.   if (max_index(v) != 2)
  166.   {
  167.     #display("qpkg_cmp: bad format: ", range, "\tV=", v, "\n"); 
  168.     return;
  169.   }
  170.   cmp = chomp(v[0]); ver = chomp(v[1]);
  171. #display("cmp=", cmp, "\tver=", ver, "\n");
  172.   ret = qpkg_ver_cmp(ver: version, ref: ver, op: cmp);
  173. #  if (ret > 0) display(version, " ", cmp, " ", ver, "\n");
  174.   return ret;
  175. }
  176.  
  177. function qpkg_check(package, vulnerable, unaffected, arch)
  178. {
  179.   local_var    fU, fV, l, v, name, ver;
  180.  
  181.   if (! qpkg_list) qpkg_list = get_kb_item("Host/Gentoo/qpkg-list");
  182.   my_arch = get_kb_item("Host/Gentoo/arch");
  183.   # Debug
  184.   if (COMMAND_LINE && ! qpkg_list && islocalhost())
  185.     qpkg_list = pread(cmd: "qpkg", argv: make_list("qpkg", "-nc", "-I", "-v"));
  186.   if (! qpkg_list) { return; }
  187.  
  188.   if (arch && my_arch && my_arch >!< arch) return 0;
  189.  
  190.   l = egrep(string: qpkg_list, pattern: strcat(package, "-[0-9]"));
  191.   # several version of a same package may be installed
  192.   ret = NULL;
  193.   foreach from_qpkg (split(l, keep:0))
  194.   {
  195.      v = eregmatch(string: from_qpkg, icase: 1,
  196.              pattern: '^[a-z0-9-]+/([a-z_-]|[^-][0-9])+-([0-9a-z._-]+)$');
  197.      if (isnull(v))
  198.      {
  199.        #display("qpkg_check: cannot parse ", from_qpkg, "\n");
  200.        # continue does not exist in 2.0.x and will do a parse error
  201.      }
  202.      else
  203.      {
  204.      name = v[1]; ver = v[2];
  205.  
  206.      foreach p (vulnerable)
  207.      {
  208.         fV = NULL; fU = NULL;
  209.  
  210.         f = qpkg_cmp(pkg: from_qpkg, version: ver, range: p);
  211.         if (f == 1)
  212.         {
  213. #          display("vulnerable: ", p, "\n");
  214.           fV = 1;
  215.           break;
  216.         }
  217.         if (isnull(fV)) fV = f;
  218.       }
  219.  
  220.      foreach p (unaffected)
  221.      {
  222.         f = qpkg_cmp(pkg: from_qpkg, version: ver, range: p);
  223.         if (f == 1)
  224.         {
  225. #          display("unaffected: ", p, "\n");
  226.           fU = 1;
  227.           break;
  228.         }
  229.         if (isnull(fU)) fU = f;
  230.       }
  231.      if (fV > 0 && fU < 1) return 1;
  232.      }
  233.    }
  234.   return 0;
  235. }
  236.